package com.atguigu.exam.service.impl;

import com.atguigu.exam.entity.AnswerRecord;
import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.AnswerRecordMapper;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.service.AIService;
import com.atguigu.exam.service.AnswerRecordService;
import com.atguigu.exam.service.ExamRecordService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.utils.GradingResult;
import com.atguigu.exam.vo.ExamRankingVO;
import com.atguigu.exam.vo.StarExamVo;
import com.atguigu.exam.vo.SubmitAnswerVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 考试记录Service实现类
 * 实现考试记录相关的业务逻辑
 */
@Transactional
@Service
public class ExamRecordServiceImpl extends ServiceImpl<ExamRecordMapper, ExamRecord> implements ExamRecordService {
    @Autowired
    private PaperService paperService;
    private StarExamVo startExamVo;
    private AnswerRecordService answerRecordService;
    private AnswerRecordMapper answerRecordMapper;
    private AIService aiService;

    @Override
    public ExamRecord startExam(StarExamVo starExamVo) {
    //根据考试姓名、试卷id和考试状态查询考试记录
    //创建LambdaQueryWrapper对象
    LambdaQueryWrapper<ExamRecord> examRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
    //封装查询条件
    examRecordLambdaQueryWrapper
            .eq(StringUtils.hasLength(starExamVo.getStudentName()), ExamRecord::getStudentName, starExamVo.getStudentName())
            .eq(startExamVo.getPaperId()!=null,ExamRecord::getExamId, starExamVo.getExamId())
            .eq(ExamRecord::getStatus,"进行中");
    //调用待条件查询的方法
    ExamRecord examRecord = baseMapper.selectOne(examRecordLambdaQueryWrapper);
    //判断是否查到考试记录
    if(examRecord == null){
        //未查到,创建新的考试记录
        examRecord = new ExamRecord();
        //设置属性值
        examRecord.setStudentName(starExamVo.getStudentName());
        //设置试卷ID
        examRecord.setExamId(starExamVo.getPaperId());
        //设置开始考试的时间
        examRecord.setStartTime(LocalDateTime.now());
        //设置考试状态为进行中
        examRecord.setStatus("进行中");
        //将考试记录保存到数据库
        baseMapper.insert(examRecord);
    }
    return examRecord;
}

    @Override
    public ExamRecord getExamRecordById(Integer id) {
        return null;
    }
    @Override
    public void submitAnswers(Integer examRecordId, List<SubmitAnswerVo> answers) {
    //根据考试记录id查询考试记录
        ExamRecord examRecord = baseMapper.selectById(examRecordId);
        //设置考试结束时间
        examRecord.setEndTime(LocalDateTime.now());
        //设置考试状态为已完成
        examRecord.setStatus("已完成");
        //根据id更新考试记录
        baseMapper.updateById(examRecord);
        //保存用户的答题记录
        //将List<submitAnswerVo>转换为List<ExamRecordAnswer>类型
        List<AnswerRecord> answerRecordList = answers.stream().map(answer -> new AnswerRecord
                (examRecordId, answer.getQuestionId(), answer.getUserAnswer())).collect(Collectors.toList());

        //调用AnswerRecordService中批量保存的方法
        answerRecordService.saveBatch(answerRecordList);
        //调用判卷的方法
        gradePager(examRecordId);
    }

    @Override
    public void deleteExamRecordById(Integer id) {
        //进行中状态的考试记录不能删除
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getStatus, "进行中").eq(ExamRecord::getId,id));
        if(exists){
            //抛出异常
            throw new ExamException(1007,"进行中状态的考试记录不能删除");
        }
        //删除考试记录
        baseMapper.deleteById(id);
        //删除答题记录
        answerRecordMapper.delete(new LambdaQueryWrapper<AnswerRecord>().eq(AnswerRecord::getExamRecordId,id));
    }
    @Override
    public List<ExamRankingVO> getExamRanking(Integer paperId, Integer limit) {
        return baseMapper.getExamRanking(paperId,limit);
    }
//判卷的方法
    private void gradePager(Integer examRecordId) {
        //根据考试记录id查询考试记录详情
        ExamRecord examRecordDetailsById = getExamRecordDetailsById(examRecordId);
        //获取试卷中的题目
        List<Question> questions = examRecordDetailsById.getPaper().getQuestions();
        //将List<Question>转换为Map<Long, Question>
        Map<Long, Question> questionMap = questions.stream().collect(Collectors.toMap(Question::getId, question -> question));
        //获取用户的答题记录
        List<AnswerRecord> answerRecords = examRecordDetailsById.getAnswerRecords();
        //设置一个变量统计用户答对题目的数量
        AtomicInteger correctCount = new AtomicInteger();
        //遍历用户的答题记录
        answerRecords.forEach(answerRecord -> {
            //获取题目id
            Long questionId = answerRecord.getQuestionId();
            //根据题目id获取题目信息
            Question question = questionMap.get(questionId);
            //获取用户的答案
            String userAnswer = answerRecord.getUserAnswer();
            //对于非简单题，手动判断用户的答案是否正确
            if(!"TEXT".equals(question.getType())){
                //对于判断题，数据库中存储的是T或F，需要转换为TRUE或FALSE
                if("JUDGE".equals(question.getType())){
                    userAnswer = userAnswer.equals("T")?"TRUE":"FALSE";
                }
                //判断用户的答案是否正确
                if(userAnswer.equals(question.getAnswer().getAnswer())){
                    //设置用户答题记录中的得分为该题目在试卷中的分数
                    answerRecord.setScore(question.getPaperScore().intValue());
                    //设置用户答题记录中该题回答正确
                    answerRecord.setIsCorrect(1);
                    //对答对数量加1
                    correctCount.set(correctCount.get() + 1);
                }else{
                    //设置用户答题记录中的得分为该题目在试卷中的分数为0
                    answerRecord.setScore(0);
                    //设置用户答题记录中该题回答错误
                    answerRecord.setIsCorrect(0);
                }
            }else{
                //对于简答题，我们调用AI判卷
                GradingResult gradingResult = aiService.gradeTextQuestions(question,userAnswer);
                //获取AI的评分
                Integer score = gradingResult.getScore();
                //设置简答题的分数
                answerRecord.setScore(score);
                //判断简答题是否答对，如果得了满分，将isCorrect设置为1，如果得0分，设置为0，其他设置为2
                if(score.equals(0)){
                    //该简答题没有得分
                    answerRecord.setIsCorrect(0);
                    //设置ai批改意见
                    answerRecord.setAiCorrection(gradingResult.getReason());
                }else if(score.equals(question.getPaperScore().intValue())){
                    //该简单题得了满分
                    answerRecord.setIsCorrect(1);
                    //设置ai批改意见
                    answerRecord.setAiCorrection(gradingResult.getFeedback());
                    //对答对数量加1
                    correctCount.set(correctCount.get() + 1);
                }else{
                    //得了一部分分数
                    answerRecord.setIsCorrect(2);
                    //设置ai批改意见
                    answerRecord.setAiCorrection(gradingResult.getReason());
                    //对答对数量加1
                    correctCount.set(correctCount.get() + 1);
                }
            }
            //更新用户答题记录
            answerRecordMapper.updateById(answerRecord);
        });
        //获取当前试卷所有题目的总分
        int totalPaperScore = questions.stream().mapToInt(question -> question.getPaperScore().intValue()).sum();
        //计算用户的总得分
        int totalScore = answerRecords.stream().filter(answerRecord -> answerRecord.getIsCorrect() != 0).mapToInt(AnswerRecord::getScore).sum();
        //设置当前试卷的总分数
        examRecordDetailsById.setScore(totalScore);
        //调用AI给出当前考试的评语
        //设置考试记录的状态
        examRecordDetailsById.setStatus("已批阅");
        //调用AI获取考试评语
        String answer = aiService.getExamAnswer(totalScore,totalPaperScore,questions.size(),correctCount);
        //设置AI评语
        examRecordDetailsById.setAnswers(answer);
        //更新考试记录
        baseMapper.updateById(examRecordDetailsById);
    }

    private ExamRecord getExamRecordDetailsById(Integer examRecordId) {
            return null;
    }

}








